/**
 * Copyright 2008 Matthew DeLambo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.delambo.drool.modules;

import com.delambo.drool.interfaces.*;
import com.delambo.drool.pooling.*;
import com.delambo.drool.logging.*;
import com.delambo.drool.exceptions.*;
import com.google.inject.*;
import com.google.inject.name.*;
import java.util.*;

public class Drool_Module implements Module {
    public void configure(Binder binder) {
        binder.bind(Drool.Factory.class).toInstance(new Drool.Factory() {
            
            @Inject ImmutableMap.Factory imapFactory;
            @Inject @Named("CPLOG") Logger logger;
            @Inject @Named("LOGMAP") PropertyMap logPropMap;
            
            /**
             * Factory method implementation that creates a Drool pool with one
             * pool based on the identifier for the pool, and the pool and 
             * logger props.
             */
            public Drool create(String logPropsFile, String poolPropsFile, 
                    Object id) throws DroolException {
                Injector injector = getInjector();
                loadLogger(logPropsFile);
                final Map<Object, Pool_Impl> pool_map 
                        = new HashMap<Object, Pool_Impl>();
                if(pool_map.containsKey(id))
                    throw new DroolException("Pool already contains ID: " + id);
                pool_map.put(id, (Pool_Impl) getPool(poolPropsFile, injector));
                ImmutableMap<Object, Pool_Impl> pm = imapFactory.create(pool_map);
                return new Drool_Impl(pm);
            }
           
            /**
             * Factory method implementation that creates a multiple Drool pools 
             * that are defined in the map.
             */
            public Drool create(String logPropsFile, HashMap p) 
                    throws DroolException {
                Injector injector = getInjector();
                loadLogger(logPropsFile);
                final Map<Object, Pool_Impl> pool_map 
                        = new HashMap<Object, Pool_Impl>();
                Iterator pi = p.keySet().iterator();
                while(pi.hasNext()) {
                    Object id = pi.next();
                    String propsFile = (String) p.get(id);
                    if(pool_map.containsKey(id))
                        throw new DroolException("Pool already contains ID: "+id);
                    pool_map.put(id, (Pool_Impl) getPool(propsFile, injector));
                }
                ImmutableMap<String, Pool_Impl> pm = imapFactory.create(pool_map);
                return new Drool_Impl(pm);
            }       

            private Pool getPool(String props, Injector injector) {
                Pool.Factory pf = injector.getInstance(Pool.Factory.class);
                Pool pool = pf.create(props);
                pool.startPool();
                return pool;
            }

            private void loadLogger(String logPropsFile) {
                logPropMap.loadProperties(logPropsFile);
                logger.init(logPropMap);
                LoggerFactory.setLogger(logger);
            }
            
            private Injector getInjector() {
                return Guice.createInjector(new Pool_Module(),
                    new AtomicLockingArray_Module(), new DataSource_Module(), 
                    new CleanerThread_Module(), new PoolNode_Module(),
                    new PropertyMap_Module(), new Resource_Module(),
                    new CircularIndexPointer_Module(), new Logger_Module());
            }
            
        });
    }
}
